package demo8

import (
	"fmt"
	"sync"
)

var wg2 sync.WaitGroup

/*
	带缓冲的通道
		1. 有缓冲的通道（buffered channel）是一种在被接收前能存储一个或者多个值的通道.
		2. 这种类型的通道并不强制要求 goroutine 之间必须同时完成发送和接收。通道
		3. 通道会阻塞发送和接收动作的条件也会不同。只有在通道中没有要接收的值时，接收动作才会阻塞。
			只有在通道没有可用缓冲区容纳被发送的值时，发送动作才会阻塞。
		4. 这导致有缓冲的通道和无缓冲的通道之间的一个很大的不同：
			无缓冲的通道保证进行发送和接收的 goroutine 会在同一时间进行数据交换；有缓冲的通道没有这种保证。
		5. 如果快递员将快递放入快递柜中，并通知用户来取，快递员和用户就成了异步收发过程，效率可以有明显的提升。
			带缓冲的通道就是这样的一个“快递柜”
*/

// TODO: 不会退出的问题

// TestDemo88 带缓冲的通道
func TestDemo88() {
	// 创建带缓冲通道
	// 通道实例 := make(chan 通道类型, 缓冲大小)

	wg2.Add(1)

	// 创建一个3个元素缓冲大小的整型通道
	ch := make(chan int, 3)

	// 查看当前 channel 的大小
	fmt.Println(len(ch))

	go func() {
		defer wg2.Done()
		fmt.Println("goroutine-------")

		// for 来获取值
		for {
			res, ok := <-ch

			if !ok {
				fmt.Println("goroutine end")
				close(ch)
				return
			}
			fmt.Println(res)
		}
	}()

	// 发送 3 个 int 到通道中
	ch <- 1
	ch <- 2
	ch <- 3

	fmt.Println(len(ch))

	fmt.Println("demo88-----main")
	wg2.Wait()
}

/*
	tips:
		带缓冲通道在下面列举的情况下依然会发生阻塞：
			1. 带缓冲通道被填满时，尝试再次发送数据时发生阻塞。
			2. 带缓冲通道为空时，尝试接收数据时发生阻塞。

		限制通道的长度有利于约束数据提供方的供给速度，供给数据量必须在消费方处理量+通道长度的范围内，才能正常地处理数据。
*/
